package slog

import (
	"context"
	"fmt"
)

type Option func(*Options)

type Options struct {
	// AppName is application nickname
	AppName string
	//LevelStr is human-readable level config
	LevelStr string `yaml:"level"`
	// The logging level the logger should log at. default is `InfoLevel`
	LogLevel Level
	//Outs logging out way, like console file or other
	Outs []string `yaml:"mode"`
	//LogFile is log file name
	LogFile string `yaml:"outfile"`
	//Style will determine the format of log, like json or console line !
	Style string `yaml:"style"`
	//TimeFormat format time with layout like 2006-01-02 15:04:05
	TimeFormat string `yaml:"time_format"`
	// Caller skip frame count for file:line info
	CallerSkipCount int `yaml:"caller_skip_count"`
	// TraceLevel will add stack trace, must greater than info. default close
	TraceLevel string `yaml:"trace_level"`
	//TimeSplit will split log by time
	TimeSplit string `yaml:"time_split"`
	//SizeSplit will split log by size
	SizeSplit int64 `yaml:"size_split"`
	// Alternative options
	Context context.Context
}

func WithAppName(name string) Option {
	return func(args *Options) {
		args.AppName = fmt.Sprintf("[%s]", name)
	}
}

// WithLevel set default level for the logger
func WithLevel(level Level) Option {
	return func(args *Options) {
		args.LogLevel = level
	}
}

// WithOutput set default output writer for the logger
func WithOutput(out []string) Option {
	return func(args *Options) {
		args.Outs = out
	}
}

// WithCallerSkipCount set frame count to skip
func WithCallerSkipCount(c int) Option {
	return func(args *Options) {
		args.CallerSkipCount = c
	}
}

func SetOption(k, v interface{}) Option {
	return func(o *Options) {
		if o.Context == nil {
			o.Context = context.Background()
		}
		o.Context = context.WithValue(o.Context, k, v)
	}
}
